package com.xzone.material.security.service

import io.jsonwebtoken.*
import io.jsonwebtoken.io.Decoders
import io.jsonwebtoken.security.Keys
import org.springframework.beans.factory.annotation.Value
import org.springframework.stereotype.Service
import java.util.*
import javax.crypto.SecretKey

@Service
class TokenService {

    @Value("\${jwt.secret:477f232a56064c4b97442b00b893c983477f232a56064c4b97442b00b893c983477f232a56064c4b97442b00b893c983477f232a56064c4b97442b00b893c983}")
    private val SECRET: String? = null

    @Value("\${jwt.exp:86400000}")
    private val EXP: Long = 0

    fun secretKey(): SecretKey {
        return Keys.hmacShaKeyFor(Decoders.BASE64.decode(SECRET))
    }

    fun createToken(tokenPayload: Map<String, Any>): String {
        val jid = UUID.randomUUID().toString()
        val token: String = Jwts.builder().signWith(secretKey(), Jwts.SIG.HS256) // 自定义字段, 需在最前面, 否则会覆盖其它
            .claims(tokenPayload)
            .id(jid) // jti, 编号
            .subject("JWT") // sub, 主题
            .issuer("AUTH") //iss, 签发人
            .expiration(Date(System.currentTimeMillis() + EXP)) //exp, 过期时间
            .notBefore(Date()) //nfb, 生效时间
            .issuedAt(Date()) //iat, 签发时间
            .compact()

        return token
    }

    fun checkToken(token: String): Boolean {
        try {
            val payload = Jwts.parser().verifyWith(secretKey()).build().parseSignedClaims(token).payload
            return payload.expiration.after(Date())
        } catch (e: ExpiredJwtException) {
            return false
        } catch (e: UnsupportedJwtException) {
            return false
        } catch (e: MalformedJwtException) {
            return false
        }
    }

    fun getUserId(token: String): String {
        return Jwts.parser().verifyWith(secretKey()).build().parseSignedClaims(token).payload["userId"].toString()
    }
}